/*
 * Copyright 2010-2016 icl-network.com. All rights reserved.
 * Support: http://www.icl-network.com
 */
package com.sinochem.yunlian.ship.common.util;

import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.alibaba.fastjson.JSON;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.poi.util.IOUtils;

/**
 * Utils -
 * 
 * @author pan
 * @version 5.0
 */
public final class HTTPUtils {
	
	private static Log logger = LogFactory.getLog(HTTPUtils.class);


    /** UTF-8字符集编码 */
    public static final String UTF_8 = "UTF-8";

    /**
     * 不可实例化
     */
    private HTTPUtils() {

    }

    /**
     * 获取响应信息
     *
     * @param url 请求地址
     * @param Map 请求参数
     * @return 响应数据
     */
    public static Map<String, String> getGetResp(String url, Map<String,Object> httpParameters)  {
        List<NameValuePair> postParams = new ArrayList<NameValuePair>();
        for (String key : httpParameters.keySet()) {
            postParams.add(new BasicNameValuePair(key, String.valueOf(httpParameters.get(key))));
        }
        return getGetResp(url, postParams, "UTF-8");
    }

    /**
     * 获取响应信息
     * 
     * @param url 请求地址
     * @param httpParameters 请求参数
     * @return 响应数据
     */
    public static Map<String, String> getGetResp(String url, List<NameValuePair> httpParameters)  {
        return getGetResp(url, httpParameters, "GB2312");
    }

    /**
     * 获取响应信息
     *
     * @param url 请求地址
     * @param httpParameters 请求参数
     * @return 响应数据
     */
    public static Map<String, String> getGetResp(String url, List<NameValuePair> httpParameters, String charset) {
        String sendstr = null;
        if (httpParameters != null && httpParameters.size() > 0)
            try {
                sendstr = "?" + EntityUtils.toString(new UrlEncodedFormEntity(httpParameters, UTF_8));
            } catch (Exception e) {
                e.printStackTrace();
                return Collections.emptyMap();
            } 

        // URL封装
        HttpGet httpGet = new HttpGet(url);
        try {
            httpGet.setURI(new URI(httpGet.getURI().toString() + sendstr));
        } catch (URISyntaxException e) {
            e.printStackTrace();
            return Collections.emptyMap();
        }

        // 获取http请求响应内容
        Map<String, String> responseMap = getHttpResponseMap(httpGet, charset);
        responseMap.put("requestBody", getBody(httpParameters).toString());
        return responseMap;
    }

    /**
     * 获取响应信息
     * 
     * @param url 请求地址
     * @param json 请求参数
     * @return 响应数据
     */
    public static Map<String, String> getPostResp(String url, String json) {
        HttpPost httpPost = new HttpPost(url);
        httpPost.addHeader("Content-Type", "application/json");
        StringEntity httpEntity = new StringEntity(json, Charset.forName(UTF_8));
        httpPost.setEntity(httpEntity);

        // 获取http请求响应内容
        Map<String, String> responseMap = getHttpResponseMap(httpPost, UTF_8);
        responseMap.put("requestParam", json);
        return responseMap;
    }

    /**
     * 获取响应信息
     *
     * @param url 请求地址
     * @param params 请求参数
     * @return 响应数据
     */
    public static Map<String, String> getPostByFormResp(String url, Map<String,Object> params)  {
        List<NameValuePair> postParams = new ArrayList<NameValuePair>();
        for (String key : params.keySet()) {
            postParams.add(new BasicNameValuePair(key, String.valueOf(params.get(key))));
        }

        return getPostByFormResp(url,postParams);
    }

    /**
     * 获取响应信息
     *
     * @param url 请求地址
     * @param httpParameters 请求参数
     * @return 响应数据
     */
    public static Map<String, String> getPostByFormResp(String url, List<NameValuePair> httpParameters)  {
        HttpPost httpPost = new HttpPost(url);
        httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
        httpPost.setEntity(new UrlEncodedFormEntity(httpParameters, Charset.forName(UTF_8)));

        // 获取http请求响应内容
        Map<String, String> responseMap = getHttpResponseMap(httpPost, UTF_8);
        responseMap.put("requestBody", getBody(httpParameters).toString());
        return responseMap;
    }

    /**
     * 请求HTTP 并把响应内容封装为Map类型
     * 
     * @param request HTTP请求
     * @param charset 响应字符集处理
     * @return HTTP请求的响应内容
     * @throws Exception
     */
    private static Map<String, String> getHttpResponseMap(HttpUriRequest request, String charset) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse httpResponse;
        try {
            //执行请求
            httpResponse = httpClient.execute(request);
        } catch (Exception e) {
            e.printStackTrace();
            return Collections.emptyMap();
        } 
        String responseBody;
        try {
            //获取响应体
            responseBody = EntityUtils.toString(httpResponse.getEntity(), charset);
            logger.debug("相应报文==========："+responseBody);
        } catch (Exception e) {
            e.printStackTrace();
            return Collections.emptyMap();
        } 
        //获取响应码
        int responseStatus = httpResponse.getStatusLine().getStatusCode();
        
        // 流关闭
        IOUtils.closeQuietly(httpResponse);
        IOUtils.closeQuietly(httpClient);

        // HTTP响应内容处理
        Map<String, String> map = new HashMap<String, String>();
        map.put("requestUrl", request.getURI().toString());
        map.put("requestMethod", request.getMethod());
        map.put("requestTime", DateUtils.formatDate(new Date(),"yyyy-MM-dd HH:mm:ss"));
        map.put("requestHeaders", getHeaders(request.getAllHeaders()));
        map.put("responseStatus", String.valueOf(responseStatus));
        map.put("responseBody", responseBody);
        map.put("responseTime", DateUtils.formatDate(new Date(),"yyyy-MM-dd HH:mm:ss"));
        map.put("responseHeaders", getHeaders(httpResponse.getAllHeaders()));
        return map;
    }

    /**
     * 获取通信头部信息
     *
     * @param headers 数组
     * @return 响应数据
     */
    private static String getHeaders(Header... headers) {
        StringBuffer headerstr = new StringBuffer();
        if (headers != null && headers.length > 0) {
            for (Header header : headers) {
                headerstr.append(header.getName());
                headerstr.append("→");
                headerstr.append(header.getValue());
                headerstr.append("|");
            }
        }
        return headerstr.toString();
    }

    /**
     * 获取通信参数信息
     *
     * @param httpParameters 参数列表
     * @return 响应数据
     */
    private static String getBody(List<NameValuePair> httpParameters) {
        if (httpParameters == null || httpParameters.isEmpty()) {
            return "";
        }
        StringBuffer requestBody = new StringBuffer();
        Iterator<NameValuePair> it = httpParameters.iterator();
        while (it.hasNext()) {
            NameValuePair parameter = (NameValuePair) it.next();
            String encodedName = parameter.getName();
            String encodedValue = parameter.getValue();
            if (requestBody.length() > 0) {
                requestBody.append("&");
            }
            requestBody.append(encodedName);
            if (encodedValue != null) {
                requestBody.append("=");
                requestBody.append(encodedValue);
            }
        }
        return requestBody.toString();
    }
    
    public static void main(String[] args) {
        Map<String,Object> params = new HashMap<>();
        params.put("method","boat.queryGoldChain");
        params.put("app_key","app_key");
        params.put("timestamp",DateUtils.formatDate(new Date(),"yyyy-MM-dd HH:mm:ss"));
        params.put("sign","sign");
        Map<String,Object> dataMap = new HashMap<>();
        dataMap.put("no","D201803290072");
        params.put("data", JSON.toJSONString(dataMap));
        Map<String,String> result = HTTPUtils.getPostByFormResp("http://10.26.2.87:9701",params);
        System.out.print(result);
    }


}